<?php defined('SYSPATH') OR die('No direct access allowed.');


/**
 * 
 * @author Thoer
 * Timepicker: http://www.jnathanson.com/index.cfm?page=jquery/clockpick/ClockPick
 * Datepicker: http://keith-wood.name/datepick.html#quick
 * 
 * 
 * Most relevant Datepicker options with default values
 * defaultDate: null, // Used when field is blank: actual date, 
 *     // +/-number for offset from today, null for today 
 * yearRange: '-10:+10', // Range of years to display in drop-down, 
 * 
 * 
 * Datepicker css is outdated, but is based on an old vesion of the official ui-datepicker:
 * http://jqueryui.com/demos/datepicker/
 * History hints here: http://marcgrabanski.com/code/ui-datepicker
 */
class Date_Plugin extends WB_FormItem {
	
	protected $db_type = 'datetime';		//valid types: int, date, datetime, timestamp
	protected $db_is_null = FALSE;
	protected $null_value = '0000-00-00 00:00:00';
	protected $on_update = FALSE;			//insert current date and time on update  
											//when hidden, item will have a hidden input field but it's value will not be used
											//when visible, form will get populated with current date but it can be changed
	protected $on_insert = FALSE;			//insert current date and time on insert
	protected $hidden = FALSE;				//show current date
	protected $format = 'Y-m-d';			//format only affects table views
	protected $time_attributes = array();
	protected $datepicker = array();
	protected $timepicker = array();
	protected $min = null;
	protected $max = null;
	
	
	public function __construct($name, $params)
	{
		parent::__construct($name, $params, 'text date');
		
		$this->db_type = isset($this->params['db_type']) ? $this->params['db_type'] : $this->db_type;
		$this->db_is_null = isset($this->params['db_is_null']) ? $this->params['db_is_null'] : $this->db_is_null;
		$this->on_update = in_array('on_update', $this->params, TRUE);
		$this->on_insert = in_array('on_insert', $this->params, TRUE);
		$this->hidden = in_array('hidden', $this->params, TRUE);
		$this->format = 
				isset($this->params['format']) ? 
					$this->params['format'] : 
					(
						$this->db_type=='date' ?
							'Y-m-d':
							'Y-m-d H:i'
					);
		if ( ! $this->format) $this->format = $this->db_type=='date' ? 'Y-m-d' : 'Y-m-d H:i:s';
		if (isset($this->params['min']))
		{
			$min = $this->params['min'];
			$this->min = is_numeric($min) ? mktime(date('H'), date('i'), date('s'), date('m'), date('d'), date('Y')+$min) : $this->int_value($min);
		}
		if (isset($this->params['max']))
		{
			$max = $this->params['max'];
			$this->max = is_numeric($max) ? mktime(date('H'), date('i'), date('s'), date('m'), date('d'), date('Y')+$max) : $this->int_value($max);
		}
		
		if ($this->db_is_null) $this->null_value = 'NULL';
		elseif ($this->db_type=='date') $this->null_value = '0000-00-00';
		else $this->null_value = '0000-00-00 00:00:00';
		
		if ($this->db_type!='date') $this->db_columns[$this->name.'_time'] = NULL;
		
		
		//JavaScript
		$this->time_attributes = isset($params['time_attributes']) ? $params['time_attributes'] : $this->time_attributes;
		$this->datepicker = isset($this->params['datepicker']) ? $this->params['datepicker'] : $this->datepicker;
		$this->datepicker['dateFormat'] = "yy-mm-dd";
		$this->timepicker = isset($this->params['timepicker']) ? $this->params['timepicker'] : $this->timepicker;
		$this->timepicker['useBgiframe'] = TRUE;
		$this->timepicker['military'] = TRUE;
		$this->timepicker['minutedivisions'] = isset($this->timepicker['minutedivisions']) ? $this->timepicker['minutedivisions'] : 12;
		
		$this->table_class = 'date';
		
		if ( ! $this->hidden) Event::add('wb_controller.pre_render_form', array($this, 'init_form'));
    }
	
	/**
	 * Sets the value of a form item
	 * 
	 * @param mixed $value
	 * @return void
	 */
	public function set_value($value, $type='init')
	{
		if ($this->on_update || ($this->on_insert && $type=='init')) $this->value = mktime();
		elseif ( ! $this->hidden || in_array($type, array('init', 'table', 'form'))) 
		{
			$value = trim(is_array($value) ? $value[$this->name].' '.$value[$this->name.'_time'] : $value);
			$this->value = $this->int_value($value);
			if ($this->min) $this->value = max($this->min, $this->value);
			if ($this->max) $this->value = min($this->max, $this->value);
		}
		else $this->value = NULL;
		//Kohana::log('info', 'Date_Plugin->set_value(type='.$type.'): '.print_r($value, TRUE).' -> '.$this->value.'('.gettype($this->value).')');
	}
	
	/**
	 * Validates date and prepares for database
	 * 
	 * @return mixed
	 */
	public function prep_db()
	{
		$value = $this->value;
		
		if ($value==0) return $this->null_value;
		elseif ($this->db_type=='int') return $value;
		else return date($this->format, $value);
	}

	
	/**
	 * Renders the form element
	 * 
	 * @return string
	 */
	public function render_item()
	{
		if (empty($this->value)) $this->set_value($this->value, 'init');
		if ($this->hidden)
		{
			$str = '<input type="hidden" name="'.$this->name.'" id="'.$this->name.'" value="'.$this->value.'" />';
		}
		else
		{
			$this->attributes['class'] = isset($this->attributes['class']) ? $this->attributes['class'].' datepicker' : 'datepicker';
			
			$str = $this->prefix;
			$str .= form::label($this->name, $this->label);
			$str .= form::input($this->name, date('Y-m-d', $this->value), html::attributes($this->attributes));
			if ($this->db_type!='date')
			{
				$time_attributes = $this->time_attributes;
				$time_attributes['class'] = isset($time_attributes['class']) ? $time_attributes['class'].' timepicker' : 'timepicker';
				$str .= form::input($this->name.'_time', date('H:i', $this->value), html::attributes($time_attributes));
			}
			if ($this->description) $str .= '<span class="description">'.$this->description.'</span>';
			$str .= $this->suffix;
		}
		
		return $str;
	}
	
	/**
	 * Returns html value for a form item
	 * 
	 * @param mixed $value
	 * @return string
	 */
	public function render_cell()
	{
		return 
			$this->value==0 ?
					Kohana::lang('date_plugin.not_set') :
					date($this->format, $this->value);
	}
	
	function init_form()
	{
		Kohana::instance()->wb_template->css('datepicker', 'plugins/datepick.css');
		Kohana::instance()->wb_template->js('plugins/datepicker/jquery.datepick.min');
		Kohana::instance()->wb_template->js('plugins/datepicker/jquery.datepick-'.substr(Kohana::config('locale.language.0'), 0, 2));
		Kohana::instance()->wb_template->js('plugins/date');
		
		
		if ($this->db_type!='date') 
		{
			Kohana::instance()->wb_template->css('clockpick', 'plugins/ui.clockpick.css');
			Kohana::instance()->wb_template->js('plugins/ui.clockpick');
			Kohana::instance()->wb_template->js('plugins/jquery.bgiframe.min');
		}
		Kohana::instance()->wb_template->script($this->name.'Date', $this->_get_js_template());
	}
	
	public function _get_js_template()
	{
		$do = json_encode($this->datepicker);
		$to = json_encode($this->timepicker);
		$template = '
$(document).ready(function(){
	$("#'.$this->name.'").datepick('.$do.');
	$("#'.$this->name.'_time").clockpick('.$to.');
});
		';
		return $template;
	}
	
	/**
	 * Sets the value of a form item
	 * 
	 * @param mixed $value
	 * @return void
	 */
	public function int_value($value)
	{
		if (empty($value)) return 0;
		elseif (is_numeric($value)) return (int)$value;
		else
		{
			if (strpos($value, '0000-00-00')===0) return 0;
			
			$parts = explode(' ', $value);
			
			if ( ! isset($parts[1]))
			{
				$parts[1] = Kohana::instance()->wb_db->get_last_row($this->name.'_time');
			}
			
			$time = empty($parts[1]) ? array(0, 0, 0) : explode(':', $parts[1]);
			$time[1] = empty($time[1]) ? 0 : $time[1];
			$time[2] = empty($time[2]) ? 0 : $time[2];
			$date = explode('-', $parts[0]);
			
			if (count($time)!=3 || count($date)!=3) throw new Kohana_Exception('date.invalid_value');
			foreach ($time as $t) if ( ! is_numeric($t)) throw new Kohana_Exception('date.invalid_value');
			foreach ($date as $d) if ( ! is_numeric($d)) throw new Kohana_Exception('date.invalid_value');
			
			return mktime($time[0], $time[1], $time[2], $date[1], $date[2], $date[0]);
		}
	}
}

//End of Date_Plugin Library